﻿using Microsoft.Extensions.DependencyModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace EasyCore.Reflection
{
    /// <summary>
    /// 程序集管理器
    /// </summary>
    public static class AssemblyManager
    {        
        /// <summary>
        /// 所有程序集
        /// </summary>
        private static Assembly[] _allAssemblies;
        
        /// <summary>
        /// 所有类型
        /// </summary>
        private static Type[] _allTypes;

        /// <summary>
        /// 过滤条件
        /// </summary>
        private static readonly string[] Filters = { "dotnet-", "Microsoft.", "mscorlib", "netstandard", "System", "Windows" };

        /// <summary>
        /// 设置程序集过滤器
        /// </summary>
        public static Func<AssemblyName, bool> AssemblyFilterFunc { private get; set; }

        /// <summary>
        /// 访问锁对象
        /// </summary>
        private static object _lockObj = new object();

        /// <summary>
        /// 静态构造函数
        /// </summary>
        static AssemblyManager()
        {
            AssemblyFilterFunc = name =>
            {
                //用于排除.net相关的程序集
                return name.Name != null && !Filters.Any(m => name.Name.StartsWith(m));
            };
        }

        /// <summary>
        /// 获取所有程序集
        /// </summary>
        public static Assembly[] AllAssemblies
        {
            get
            {
                lock (_lockObj)
                {
                    if (_allAssemblies != null) return _allAssemblies;
                    Init();
                    return _allAssemblies;
                }
            }
        }

        /// <summary>
        /// 获取所有类型
        /// </summary>
        public static Type[] AllTypes
        {
            get
            {
                lock (_lockObj)
                {
                    if (_allTypes != null) return _allTypes;
                    Init();
                    return _allTypes;
                }
            }
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public static void Init()
        {
            _allAssemblies = DependencyContext.Default.GetDefaultAssemblyNames()
                .Where(AssemblyFilterFunc).Select(Assembly.Load).ToArray();
            _allTypes = _allAssemblies.SelectMany(m => m.GetTypes()).ToArray(); //获得程序集的所有类型
        }

        /// <summary>
        /// 查找指定条件的类型
        /// </summary>
        public static Type[] FindTypes(Func<Type, bool> predicate)
        {
            return AllTypes.Where(predicate).ToArray();
        }

        /// <summary>
        /// 查找指定基类的实现类型
        /// </summary>
        public static Type[] FindTypesByBase<TBaseType>()
        {
            Type baseType = typeof(TBaseType);
            return FindTypesByBase(baseType);
        }

        /// <summary>
        /// 查找指定基类的实现类型
        /// </summary>
        public static Type[] FindTypesByBase(Type baseType)
        {
            return AllTypes.Where(type => type.IsDeriveClassFrom(baseType)).Distinct().ToArray();
        }

        /// <summary>
        /// 查找指定Attribute特性的实现类型
        /// </summary>
        public static Type[] FindTypesByAttribute<TAttribute>(bool inherit = true)
        {
            Type attributeType = typeof(TAttribute);
            return FindTypesByAttribute(attributeType, inherit);
        }

        /// <summary>
        /// 查找指定Attribute特性的实现类型
        /// </summary>
        public static Type[] FindTypesByAttribute(Type attributeType, bool inherit = true)
        {
            return AllTypes.Where(type => type.IsDefined(attributeType, inherit)).Distinct().ToArray();
        }
    }
}
